package com.zrrd.mcl.activity.service.impl;

import com.zrrd.mcl.activity.mapper.SeckillMapper;
import com.zrrd.mcl.activity.service.SeckillGoodsService;
import com.zrrd.mcl.activity.util.CacheHelper;
import com.zrrd.mcl.common.result.Result;
import com.zrrd.mcl.common.result.ResultCodeEnum;
import com.zrrd.mcl.common.util.MD5;
import com.zrrd.mcl.model.activity.OrderRecode;
import com.zrrd.mcl.model.activity.SeckillGoods;
import com.zrrd.mcl.model.product.SkuInfo;
import com.zrrd.mcl.product.client.ProductFeiginClient;
import com.zrrd.mcl.service.constant.RedisConst;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class SeckillGoodsServiceImpl implements SeckillGoodsService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ProductFeiginClient productFeiginClient;

    @Autowired
    private SeckillMapper seckillMapper;

    @Override
    public List<SeckillGoods> getSeckillGoodsList() {
        List<SeckillGoods> list = redisTemplate.boundHashOps(RedisConst.SECKILL_GOODS).values();
        return list;
    }

    @Override
    public SeckillGoods getSeckillGoodsById(Long id) {
        SeckillGoods seckillGoods = (SeckillGoods) redisTemplate.boundHashOps(RedisConst.SECKILL_GOODS).
                get(id.toString());
        return seckillGoods;
    }

    @Override
    public void addSeckillGoods(Long skuId) {
        //获取shu基本信息
        SkuInfo skuInfo = productFeiginClient.getSkuInfo(skuId);
        //创建秒杀商品实体对象
        SeckillGoods goods = new SeckillGoods();
        goods.setSpuId(skuInfo.getSpuId());
        goods.setSkuId(skuId);
        goods.setSkuName(skuInfo.getSkuName());
        goods.setSkuDefaultImg(skuInfo.getSkuDefaultImg());
        goods.setPrice(skuInfo.getPrice());
        goods.setCostPrice(new BigDecimal(0.1));
        goods.setCreateTime(new Date());
        goods.setCheckTime(new Date());
        goods.setStatus("1");
        goods.setStartTime(new Date());
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.HOUR, 4);
        goods.setEndTime(calendar.getTime());
        goods.setNum(100);
        goods.setStockCount(10);
        goods.setSkuDesc(skuInfo.getSkuDesc());
        //保存
        seckillMapper.insert(goods);

    }

    @Override
    public void seckillOrder(Long skuId, String userId) {
        //判断状态位
        String state = (String) CacheHelper.get(skuId.toString());
        if ("0".equals(state)) {
            return;
        }
        //判断用户是否下过单
        Boolean absent = redisTemplate.opsForValue().setIfAbsent(RedisConst.SECKILL_USER + userId, skuId,
                RedisConst.SECKILL__TIMEOUT, TimeUnit.SECONDS);
        if (!absent) {
            return;
        }
        //从redis队列中获取商品
        String goodsId = (String) redisTemplate.boundListOps(RedisConst.SECKILL_STOCK_PREFIX + skuId).rightPop();
        if (StringUtils.isEmpty(goodsId)) {
            //更新状态位
            redisTemplate.convertAndSend("seckillPush", skuId + ":0");
            return;
        }
        //创建订单记录
        OrderRecode orderRecode = new OrderRecode();
        orderRecode.setUserId(userId);
        orderRecode.setNum(1);
        orderRecode.setSeckillGoods(this.getSeckillGoodsById(skuId));
        //设置订单码
        orderRecode.setOrderStr(MD5.encrypt(userId + skuId));
        //将订单数据存入Redis
        redisTemplate.boundHashOps(RedisConst.SECKILL_ORDERS).put(orderRecode.getUserId(), orderRecode);
        //更新库存
        this.updateStockCount(skuId);
    }

    @Override
    public Result checkorder(Long skuId, String userId) {

        //查询Redis缓存中是否有该用户
        Boolean isExist = redisTemplate.hasKey(RedisConst.SECKILL_USER + userId);
        if (isExist) {
            //获取订单
            OrderRecode orderRecode = (OrderRecode) redisTemplate.boundHashOps(RedisConst.SECKILL_ORDERS).get(userId);
            //秒杀成功 返回订单
            return Result.build(orderRecode, ResultCodeEnum.SECKILL_SUCCESS);
        }

        //判断是否已经下单
        Boolean hasKey = redisTemplate.boundHashOps(RedisConst.SECKILL_ORDERS_USERS).hasKey(userId);
        if (hasKey) {
            String orderId = (String) redisTemplate.boundHashOps(RedisConst.SECKILL_ORDERS_USERS).get(userId);
            return Result.build(orderId, ResultCodeEnum.SECKILL_ORDER_SUCCESS);
        }

        //判断状态位
        String state = (String) CacheHelper.get(skuId.toString());
        if ("0".equals(state)) {
            return Result.build(null,ResultCodeEnum.SECKILL_FINISH);
        }

        //正在排队
        return Result.build(null,ResultCodeEnum.SECKILL_RUN);
    }

    private void updateStockCount(Long skuId) {
        //获取队列中的数据数量
        Long size = redisTemplate.boundListOps(RedisConst.SECKILL_STOCK_PREFIX + skuId).size();
        System.out.println("获取队列中的数据数量====>" + size);
        if(size%2==0){
            //更新Mysql数据
            SeckillGoods seckillGoods = this.getSeckillGoodsById(skuId);
            seckillGoods.setStockCount(size.intValue());
            seckillMapper.updateById(seckillGoods);
            System.out.println("更新Mysql库存信息====>" + seckillGoods);
            //更新Redis数据
            redisTemplate.boundHashOps(RedisConst.SECKILL_GOODS).put(seckillGoods.getSkuId().toString(),seckillGoods);

        }
    }
}
